package com.cy.pj.sys.service.impl;

import com.cy.pj.common.annotation.RequiredLog;
import com.cy.pj.common.annotation.RequiredTime;
import com.cy.pj.sys.dao.SysLogDao;
import com.cy.pj.sys.pojo.SysLog;
import com.cy.pj.sys.service.SysLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;


/**
 * 用户日志业务规范的实现
 */
@Transactional(readOnly=false,
        timeout =60,
        rollbackFor = Throwable.class,
        isolation = Isolation.READ_COMMITTED
      )
@Service
public class SysLogServiceImpl implements SysLogService {
    @Autowired
    private SysLogDao sysLogDao;
//    public SysLogServiceImpl(SysLogDao sysLogDao){
//        this.sysLogDao=sysLogDao;
//    }
    //没有Autowired注解可以通过写一个带参构造函数 底层通过反射来获取private SysLogDao sysLogDao;
    @RequiredTime
    @RequiredLog(operation = "查询日志")   //由此注解描述的方法为日志切入点方法
    @Override
    public List<SysLog> findLogs(SysLog sysLog) {
        System.out.println("log.find.thread->" + Thread.currentThread().getName());
        System.out.println("进入 >>> findLogs()");
        //throw new RuntimeException("年纪高人工日哦国际饭店是");
        return sysLogDao.selectLogs(sysLog);
    }
@Transactional(readOnly = true)
    @RequiredTime
    @RequiredLog(operation = "查询日志")
    @Override
    public SysLog findById(Long id) {
        return sysLogDao.selectById(id);
    }

    /**
     * @Async注解描述的方法为一个异步切入点方法,这个方法执行时候底层会在新的线程中进行调用
     *
     * @param sysLog
     * @Async注解描述的方法其返回值类型建议为void],假如为非void系需要对方法
     * 返回值类型进行设计,比较说方法声明为Future<Integer>,方法内部的返回值
     * 为return new AsyncResult<Integer>(rows)
     */
    @Async //@Async注解描述的方法为一个异步切入点方法
    @Override
    public void saveLog(SysLog sysLog) {
        System.out.println("save.log.thread->" + Thread.currentThread().getName());
        //模拟耗时操作
        try { Thread.sleep(10000);}catch (Exception e){
        //try { TimeUnit.SECONDS.sleep(10);}catch (Exception e){}
            sysLogDao.insertLog(sysLog);
        }


        sysLogDao.insertLog(sysLog);
    }

    @Transactional//此注解爱你描述方法时,这个方法为一个事务切入点方法
//    @RequiredPermissions
    @RequiredLog(operation = "删除日志")
    @Override
    public int deleteById(Long... id) {
        for (int i = 0; i<id.length; i++) {
            if (i==1){
                //这里抛出异常时如何让已删除的数据回滚
                throw new RuntimeException("删除失败");
            }
            sysLogDao.deleteById(id[i]);
        }
        //return sysLogDao.deleteById(id);
        return 10;
    }
}
